//! # role
//!
//! 该类型表示武将信息

use super::{Gender, Power};

/// 武将
#[derive(Debug, Clone, PartialEq, Default)]
pub struct Role {
    /// 体力值
    pub hp: usize,

    /// 体力上限
    pub max_hp: usize,

    /// 武将名称
    pub name: String,

    /// 势力
    pub power: Power,

    /// 性别
    pub gender: Gender,

    /// 被翻面了么？
    pub turn_over: bool,
}

impl TryFrom<(&str, &str)> for Role {
    type Error = crate::Error;

    /// 从字符串解析出 Role 结构体
    ///
    /// 输入 text 应该为例如 `刘备/4/4/蜀/男` 模式
    ///
    /// 对于其他可行字符串 `刘备/4/4/SHU/M`、`李傕/4/6/QUN/M` 模式
    ///
    /// 解析失败会返回错误
    ///
    /// 可以设置第二个参数作为分隔符
    fn try_from(value: (&str, &str)) -> Result<Role, Self::Error> {
        let mut role = Role::default();

        for (index, text) in value.0.split(value.1).enumerate() {
            match index {
                0 => role.name = text.to_owned(),
                1 => role.hp = text.parse::<usize>()?,
                2 => role.max_hp = text.parse::<usize>()?,
                3 => role.power = Power::try_from(text)?,
                4 => role.gender = Gender::try_from(text)?,
                _ => break,
            }
        }
        Ok(role)
    }
}

impl TryFrom<&str> for Role {
    type Error = crate::Error;

    /// 从字符串解析出 Role 结构体
    ///
    /// 输入 text 应该为例如 `刘备/4/4/蜀/男` 模式
    ///
    /// 对于其他可行字符串 `刘备/4/4/SHU/M`、`李傕/4/6/QUN/M` 模式
    ///
    /// 解析失败会返回错误
    ///
    /// 分隔符默认为 "/"
    fn try_from(value: &str) -> Result<Role, Self::Error> {
        Self::try_from((value, "/"))
    }
}

#[cfg(test)]
mod test {

    use super::*;

    #[test]
    fn test_try_from_str() {
        let want = Role {
            hp: 4,
            max_hp: 4,
            name: "刘备".to_string(),
            power: Power::SHU,
            gender: Gender::Male,
            ..Default::default()
        };

        let get = Role::try_from("刘备/4/4/蜀/男").unwrap();

        assert_eq!(want, get);
        assert!(Role::try_from("刘备/4/4/?").is_err());
        assert!(Role::try_from("刘备/4/4/蜀/男///").is_ok());
    }
}
